package com.example.springbootdemo.config;

import com.alibaba.fastjson.JSON;
import com.example.springbootdemo.mapper.UserInfoMapper;
import com.example.springbootdemo.mapper.UserMapper;
import com.example.springbootdemo.vo.UserInfoVo;
import com.example.springbootdemo.vo.UserVo;
import com.example.springbootdemo.util.TimestampUtil;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 第三方登录用户异步新增
 *
 * @author 84246
 */
@Getter
@Configuration
@Slf4j
@Data
public class ThreadConfig implements Runnable, ApplicationContextAware {
    @PostConstruct
    private void initThread() {
        userMapper = applicationContext.getBean(UserMapper.class);
        userInfoMapper = applicationContext.getBean(UserInfoMapper.class);
        ThreadConfig threadConfig = new ThreadConfig();
        threadConfig.setUserInfoMapper(userInfoMapper);
        threadConfig.setUserMapper(userMapper);
        new Thread(threadConfig).start();
    }

    ApplicationContext applicationContext;
    @Setter
    private UserMapper userMapper;
    @Setter
    private UserInfoMapper userInfoMapper;
    // 最多缓存 50条信息
    public static final BlockingQueue<Map<String, Object>> BLOCKING_QUEUE = new LinkedBlockingQueue<>();

    @Override
    public void run() {
        while (true) {
            if (BLOCKING_QUEUE.isEmpty()) {
                // 如果阻塞队列里没有元素，阻塞1s
                try {
                    Thread.sleep(1000);
                    continue;
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            List<Map<String, Object>> list = new ArrayList<>();
            BLOCKING_QUEUE.drainTo(list);
            for (Map<String, Object> userMap : list) {
                try {
                    UserVo userModel = mapToUser(userMap);
                    if (!checkUser(userModel)) {
                        userMapper.insertUser(userModel);
                    }
                    UserInfoVo userInfoModel = mapToUserInfo(userMap);
                    if (!checkUserInfo(userInfoModel)) {
                        userInfoMapper.insertUserInfo(userInfoModel);
                    }
                } catch (Exception exception) {
                    // 如果报错只能当前用户报错，记录日志信息，其他线程正常入参
                    log.error("add user or userinfo error,info,{}  ", JSON.toJSONString(userMap), exception);
                }
            }
        }

    }

    public static UserInfoVo mapToUserInfo(Map<String, Object> userMap) throws Exception {
        if (userMap.get("login") == null) {
            throw new Exception("login is null");
        }
        UserInfoVo userInfoModel = new UserInfoVo();
        userInfoModel.setUserName(String.valueOf(userMap.get("login")));
        userInfoModel.setUserNick(String.valueOf(userMap.get("name")));
        // 将第三方ID作为我方ID即可
        userInfoModel.setId(String.valueOf(userMap.get("id")));
        // 当前时间
        userInfoModel.setUpdateTime(TimestampUtil.valueOf(new Date()));
        userInfoModel.setUserImgUrl(String.valueOf(userMap.get("avatar_url")));
        return userInfoModel;
    }

    public static UserVo mapToUser(Map<String, Object> userMap) {
        UserVo userModel = new UserVo();
        userModel.setUserName(String.valueOf(userMap.get("login")));
        userModel.setPassWord("System");
        userModel.setId(String.valueOf(userMap.get("id")));
        userModel.setUpdateTime(TimestampUtil.valueOf(new Date()));
        userModel.setCreateTime(TimestampUtil.valueOf(new Date()));
        userModel.setCreateBy("System");
        // 第三方用户
        userModel.setRoleId(3);
        return userModel;
    }

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        applicationContext = context;
    }

    private boolean checkUser(UserVo input) {
        UserVo output = userMapper.thirdPartyLogins(input);
        return output != null;
    }

    private boolean checkUserInfo(UserInfoVo input) {
        UserInfoVo userInfoModel1 = userInfoMapper.thirdPartyLogins(input);
        return userInfoModel1 != null;
    }

}
